﻿using InnoWeb.CEND.Data.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InnoWeb.CEND.Data
{
    using InnoWeb.CEND.Core.Model.Base;
    using System.Data;
    using System.Data.Entity;

    public class GenericRepository<T> : IRepository<T> where T : BaseEntity<int>
    {
        //private IUnitOfWork _unitOfWork;
        private WebSiteContext _dbContext;
        private DbSet<T> _entity;

        //public GenericRepository()
        //{
        //}

        public GenericRepository(DbContext dbContext)
        {
            //this._unitOfWork = unitOfWork;
            this._dbContext=(WebSiteContext)dbContext;
            _entity = this._dbContext.Set<T>();
        }

        public T GetById(object id)
        {
            return _entity.Find(id);
        }

        public IQueryable<T> GetAll()
        {
            return _entity.AsQueryable();
        }

        public IQueryable<T> SearchFor(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
        {
            return _entity.Where(predicate);
        }

        public IQueryable<T> SearchFor(params object[] keys)
        {
            throw new ArgumentNullException();
        }

        public void Insert(T entity)
        {
            _entity.Add(entity);
        }

        public void Update(T entity)
        {
            var entry = _dbContext.Entry<T>(entity);
            var pKey = _entity.Create().GetType().GetProperty("Id").GetValue(entity,null);

            if (entry.State==EntityState.Detached)
            {
                var set = _dbContext.Set<T>();
                T attachedEntity = set.Find(pKey);
                if (attachedEntity != null)
                {
                    var attachedEntry = _dbContext.Entry(attachedEntity);
                    attachedEntry.CurrentValues.SetValues(entity);
                }
                else
                {
                    entry.State = EntityState.Modified;
                }
            }
        }

        public void Delete(T entity)
        {
            _entity.Remove(entity);
        }

        public void Delete(int Id)
        {
            _entity.Remove(_entity.Find(Id));
        }

        //public IUnitOfWork UnitOfWork
        //{
        //    get { return this._unitOfWork; }
        //}
    }
}
